package com.caregiver.watch.business.data.service.impl;

import com.caregiver.watch.business.data.dao.HealthBaseDataDao;
import com.caregiver.watch.business.data.dao.HealthBloodOxygenDao;
import com.caregiver.watch.business.data.dao.HealthBloodPressureDao;
import com.caregiver.watch.business.data.dao.HealthDeviceLocationDao;
import com.caregiver.watch.business.data.dao.HealthEcgDao;
import com.caregiver.watch.business.data.dao.HealthHeartRateDao;
import com.caregiver.watch.business.data.dao.HealthHeartRateVariabilityDao;
import com.caregiver.watch.business.data.dao.HealthRriDao;
import com.caregiver.watch.business.data.dao.HealthSleepDisplayDao;
import com.caregiver.watch.business.data.dao.HealthTemperatureDao;
import com.caregiver.watch.business.data.dao.SportDataDao;
import com.caregiver.watch.business.data.enums.SportTypeEnum;
import com.caregiver.watch.business.data.model.po.HealthBaseData;
import com.caregiver.watch.business.data.model.po.HealthBloodOxygen;
import com.caregiver.watch.business.data.model.po.HealthBloodPressure;
import com.caregiver.watch.business.data.model.po.HealthDeviceLocation;
import com.caregiver.watch.business.data.model.po.HealthEcg;
import com.caregiver.watch.business.data.model.po.HealthHeartRate;
import com.caregiver.watch.business.data.model.po.HealthHeartRateVariability;
import com.caregiver.watch.business.data.model.po.HealthRri;
import com.caregiver.watch.business.data.model.po.HealthSleepDisplay;
import com.caregiver.watch.business.data.model.po.HealthTemperature;
import com.caregiver.watch.business.data.model.po.SportData;
import com.caregiver.watch.business.data.service.HealthDataQueryService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

import static com.caregiver.watch.common.constant.NumberConstants.ONE;

/**
 * @Description: 健康数据查询服务
 * @Author 疆戟
 * @Date 2025/9/24 22:38
 * @Version 1.0
 */
@AllArgsConstructor
@Service
@Slf4j
public class HealthDataQueryServiceImpl implements HealthDataQueryService {

    private final HealthBaseDataDao healthBaseDataDao;
    private final SportDataDao sportDataDao;
    private final HealthDeviceLocationDao healthDeviceLocationDao;
    private final HealthEcgDao healthEcgDao;
    private final HealthHeartRateDao healthHeartRateDao;
    private final HealthBloodPressureDao healthBloodPressureDao;
    private final HealthHeartRateVariabilityDao healthHeartRateVariabilityDao;
    private final HealthSleepDisplayDao healthSleepDisplayDao;
    private final HealthTemperatureDao healthTemperatureDao;
    private final HealthBloodOxygenDao healthBloodOxygenDao;
    private final HealthRriDao healthRriDao;

    @Override
    public HealthBaseData queryHealthBaseData(Long userId, String deviceUuId) {
        if (Objects.isNull(userId) || StringUtils.isBlank(deviceUuId)) {
            return null;
        }
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime startTime = now.minusDays(ONE).with(LocalTime.MAX);
        LocalDateTime endTime = now.with(LocalTime.MAX);
        // 获取当天最后一条数据
        return healthBaseDataDao.queryLastData(userId, deviceUuId, startTime, endTime);
    }

    @Override
    public HealthBaseData queryHealthBaseData(Long userId, String deviceUuId, LocalDateTime startTime, LocalDateTime endTime) {
        if (Objects.isNull(userId) || StringUtils.isBlank(deviceUuId)) {
            return null;
        }
        if (Objects.isNull(userId) || StringUtils.isBlank(deviceUuId) || Objects.isNull(startTime) || Objects.isNull(endTime)) {
            return null;
        }
        // 获取当天最后一条数据
        return healthBaseDataDao.queryLastData(userId, deviceUuId, startTime, endTime);
    }

    @Override
    public List<HealthBaseData> queryLastDataList(Long userId, String deviceUuid, LocalDateTime startTime, LocalDateTime endTime) {
        if (Objects.isNull(userId) || StringUtils.isBlank(deviceUuid)) {
            return new ArrayList<>();
        }
        // 开始时间和结束时间为空
        if (Objects.isNull(startTime) || Objects.isNull(endTime)) {
            return new ArrayList<>();
        }
        // 开始时间大于结束时间也返回空
        if (startTime.isAfter(endTime)) {
            return new ArrayList<>();
        }
        return healthBaseDataDao.queryLastDataList(userId, deviceUuid, startTime, endTime);
    }

    @Override
    public List<SportData> queryTodaySportData(Long userId, String deviceUuid) {
        if (Objects.isNull(userId) || StringUtils.isBlank(deviceUuid)) {
            return new ArrayList<>();
        }
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime startTime = now.minusDays(ONE).with(LocalTime.MAX);
        LocalDateTime endTime = now.with(LocalTime.MAX);
        return sportDataDao.queryUserSportData(startTime, endTime, userId, deviceUuid);
    }

    @Override
    public HealthDeviceLocation queryLatestDeviceLocationByDeviceUuid(Long userId, String deviceUuid) {
        if (Objects.isNull(userId) || StringUtils.isBlank(deviceUuid)) {
            return null;
        }
        // 获取最新的一条定位数据
        return healthDeviceLocationDao.queryLatestByDeviceUuid(userId, deviceUuid);
    }

    @Override
    public List<HealthDeviceLocation> queryDeviceLocations(Long userId,
                                                           String deviceUuid,
                                                           LocalDateTime start,
                                                           LocalDateTime end) {
        if (Objects.isNull(userId) || StringUtils.isBlank(deviceUuid) || Objects.isNull(start) || Objects.isNull(end)) {
            return new ArrayList<>();
        }
        return healthDeviceLocationDao.selectByUserIdAndTimeRange(userId, deviceUuid, start, end);
    }


    @Override
    public List<HealthEcg> queryLatestEcgData(Long userId, String deviceUuid) {
        if (Objects.isNull(userId) || StringUtils.isBlank(deviceUuid)) {
            return new ArrayList<>();
        }
        return healthEcgDao.selectLatestEcgData(userId, deviceUuid);
    }

    @Override
    public HealthHeartRate queryLatestHrData(Long userId, String deviceUuid) {
        if (Objects.isNull(userId) || StringUtils.isBlank(deviceUuid)) {
            return null;
        }
        return healthHeartRateDao.queryLatestHrData(userId, deviceUuid);
    }

    @Override
    public List<HealthHeartRate> queryHrData(Long userId, String deviceUuid, LocalDateTime startTime, LocalDateTime endTime) {
        if (Objects.isNull(userId) || StringUtils.isBlank(deviceUuid)) {
            return new ArrayList<>();
        }
        // 开始时间和结束时间为空
        if (Objects.isNull(startTime) || Objects.isNull(endTime)) {
            return new ArrayList<>();
        }
        // 开始时间大于结束时间也返回空
        if (startTime.isAfter(endTime)) {
            return new ArrayList<>();
        }
        return healthHeartRateDao.queryHrData(userId, deviceUuid, startTime, endTime);
    }

    @Override
    public HealthBloodPressure queryLatestBpData(Long userId, String deviceUuid) {
        if (Objects.isNull(userId) || StringUtils.isBlank(deviceUuid)) {
            return null;
        }
        return healthBloodPressureDao.queryLatestBpData(userId, deviceUuid);
    }

    @Override
    public List<HealthBloodPressure> queryBpData(Long userId, String deviceUuid, LocalDateTime start, LocalDateTime end) {
        if (Objects.isNull(userId) || StringUtils.isBlank(deviceUuid)) {
            return new ArrayList<>();
        }
        // 开始时间和结束时间为空
        if (Objects.isNull(start) || Objects.isNull(end)) {
            return new ArrayList<>();
        }
        // 开始时间大于结束时间也返回空
        if (start.isAfter(end)) {
            return new ArrayList<>();
        }
        return healthBloodPressureDao.queryBpData(userId, deviceUuid, start, end);
    }

    @Override
    public HealthHeartRateVariability queryLatestHrvData(Long userId, String deviceUuid) {
        if (Objects.isNull(userId) || StringUtils.isBlank(deviceUuid)) {
            return null;
        }
        return healthHeartRateVariabilityDao.queryLatestHrvData(userId, deviceUuid);
    }

    @Override
    public HealthSleepDisplay queryLatestSleepData(Long userId, String deviceUuid) {
        if (Objects.isNull(userId) || StringUtils.isBlank(deviceUuid)) {
            return null;
        }
        return healthSleepDisplayDao.findLatestByUserIdAndDeviceUuid(userId, deviceUuid);
    }

    @Override
    public HealthBloodOxygen queryLatestBloodOxygenData(Long userId, String deviceUuid) {
        if (Objects.isNull(userId) || StringUtils.isBlank(deviceUuid)) {
            return null;
        }
        return healthBloodOxygenDao.queryLatestBpData(userId, deviceUuid);
    }

    @Override
    public HealthTemperature queryLatestBodyTemperatureData(Long userId, String deviceUuid) {
        if (Objects.isNull(userId) || StringUtils.isBlank(deviceUuid)) {
            return null;
        }
        return healthTemperatureDao.queryLatestTemperatureData(userId, deviceUuid);
    }

    @Override
    public HealthSleepDisplay queryLatestSleepData(Long userId,
                                             String deviceUuid,
                                             LocalDateTime startTime,
                                             LocalDateTime endTime) {
        if (Objects.isNull(userId) || StringUtils.isBlank(deviceUuid)) {
            return null;
        }
        // 开始和结束时间没有传就查询今天的
        if (Objects.isNull(startTime) || Objects.isNull(endTime)) {
            startTime = LocalDateTime.now().minusDays(ONE).with(LocalTime.MIN);
            endTime = LocalDateTime.now().with(LocalTime.MAX);
        }
        return healthSleepDisplayDao.findLatest(userId, deviceUuid, startTime, endTime);
    }

    @Override
    public List<HealthSleepDisplay> querySleepData(Long userId, String deviceUuid, LocalDateTime start, LocalDateTime end) {
        if (Objects.isNull(userId) || StringUtils.isBlank(deviceUuid)) {
            return new ArrayList<>();
        }
        // 开始和结束时间没有传就查询今天的
        if (Objects.isNull(start) || Objects.isNull(end)) {
            start = LocalDateTime.now().minusWeeks(ONE).with(LocalTime.MIN);
            end = LocalDateTime.now().with(LocalTime.MAX);
        }
        return healthSleepDisplayDao.queryByUserIdAndTimeRange(userId, deviceUuid, start, end);
    }

    @Override
    public List<HealthHeartRateVariability> queryStressValueData(Long userId,
                                                                 String deviceUuid,
                                                                 LocalDateTime start,
                                                                 LocalDateTime end) {
        if (Objects.isNull(userId) || StringUtils.isBlank(deviceUuid)) {
            return new ArrayList<>();
        }
        if (Objects.isNull(start) || Objects.isNull(end)) {
            start = LocalDateTime.now().minusWeeks(ONE).with(LocalTime.MIN);
            end = LocalDateTime.now().with(LocalTime.MAX);
        }
        return healthHeartRateVariabilityDao.queryHrvData(userId, deviceUuid, start, end);
    }

    @Override
    public List<HealthEcg> queryEcgData(Long userId, String deviceUuid, LocalDateTime start, LocalDateTime end) {
        if (Objects.isNull(userId) || StringUtils.isBlank(deviceUuid)) {
            return new ArrayList<>();
        }
        if (Objects.isNull(start) || Objects.isNull(end)) {
            start = LocalDateTime.now().minusWeeks(ONE).with(LocalTime.MIN);
            end = LocalDateTime.now().with(LocalTime.MAX);
        }
        return healthEcgDao.queryEcgData(userId, deviceUuid, start, end);
    }

    @Override
    public List<LocalDateTime> queryExistTraceDate(Long userId, String deviceUuid, LocalDateTime start, LocalDateTime end) {
        if (Objects.isNull(userId) || StringUtils.isBlank(deviceUuid)) {
            return new ArrayList<>();
        }
        // 开始时间和结束时间为空
        if (Objects.isNull(start) || Objects.isNull(end)) {
            return new ArrayList<>();
        }
        // 开始时间大于结束时间也返回空
        if (start.isAfter(end)) {
            return new ArrayList<>();
        }
        return healthDeviceLocationDao.queryExistTraceDate(userId, deviceUuid, start, end);
    }

    @Override
    public List<HealthBloodOxygen> queryBloodOxygenData(Long userId, String deviceUuid, LocalDateTime start, LocalDateTime end) {
        if (Objects.isNull(userId) || StringUtils.isBlank(deviceUuid)) {
            return new ArrayList<>();
        }
        // 开始时间和结束时间为空
        if (Objects.isNull(start) || Objects.isNull(end)) {
            return new ArrayList<>();
        }
        // 开始时间大于结束时间也返回空
        if (start.isAfter(end)) {
            return new ArrayList<>();
        }
        return healthBloodOxygenDao.queryBloodOxygenData(userId, deviceUuid, start, end);
    }

    @Override
    public List<HealthTemperature> queryTemperatureData(Long userId, String deviceUuid, LocalDateTime start, LocalDateTime end) {
        if (Objects.isNull(userId) || StringUtils.isBlank(deviceUuid)) {
            return new ArrayList<>();
        }
        // 获取到开始时间和结束时间
        if (Objects.isNull(start) || Objects.isNull(end)) {
            return new ArrayList<>();
        }
        if (start.isAfter(end)) {
            return new ArrayList<>();
        }
        return healthTemperatureDao.queryTemperatureData(userId, deviceUuid, start, end);
    }

    @Override
    public List<SportData> querySportData(Long userId, String deviceUuid, LocalDateTime start, LocalDateTime end) {
        if (Objects.isNull(userId) || StringUtils.isBlank(deviceUuid)) {
            return new ArrayList<>();
        }
        // 获取到开始时间和结束时间
        if (Objects.isNull(start) || Objects.isNull(end)) {
            return new ArrayList<>();
        }
        if (start.isAfter(end)) {
            return new ArrayList<>();
        }
        return sportDataDao.queryUserSportData(start, end, userId, deviceUuid);
    }

    @Override
    public List<HealthRri> queryRriData(Long userId, String deviceUuid, LocalDateTime start, LocalDateTime end) {
        if (Objects.isNull(userId) || StringUtils.isBlank(deviceUuid)) {
            return new ArrayList<>();
        }
        return healthRriDao.selectByUserIdAndTime(userId, deviceUuid, start, end);
    }
}
